package se.bth.ke.firstfriend.dto.todo.helper;

import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import se.bth.ke.firstfriend.model.dto.TodoInfo;

import static se.bth.ke.firstfriend.dto.todo.helper.InvertingComparator.inverted;

/**
 *
 * @author Markus.Goetz
 * @author nico.rehwaldt
 */
public enum Order implements Sortable {

    DEADLINE ("deadline") {
        @Override
        protected Comparator<TodoInfo> getComparator() {
            return inverted(new DeadlineComparator());
        }
    },

    RELEVANCE ("relevance") {
        @Override
        protected Comparator<TodoInfo> getComparator() {
            return inverted(new RelevanceComparator());
        }
    },

    PRIORITY ("priority") {
        @Override
        protected Comparator<TodoInfo> getComparator() {
            return inverted(new PriorityComparator());
        }
    },
    
    ADDED ("added") {
        @Override
        protected Comparator<TodoInfo> getComparator() {
            return new Comparator<TodoInfo>() {
                @Override
                public int compare(TodoInfo t1, TodoInfo t2) {
                    return t1.getTodo().getCreatedAt().compareTo(t2.getTodo().getCreatedAt());
                }
            };
        }
    };

    private final String orderString;

    private Order(String order) {
        this.orderString = order;
    }
    
    public String getOrderString() {
        return this.orderString;
    }

    public static Order fromString(String orderString) {
        for (Order order : Order.values()) {
            if (order.getOrderString().equals(orderString)) {
                return order;
            }
        }
        throw new IllegalArgumentException("Order parameter " + orderString + " unknown");
    }
    
    protected abstract Comparator<TodoInfo> getComparator();

    @Override
    public final List<TodoInfo> sort(List<TodoInfo> info, boolean invert) {
        Collections.sort(info, invert ? inverted(getComparator()) : getComparator());
        return info;
    }
}
